using System.Collections.Generic;
using System.Linq;
using Engine;
using Engine.Graphics;
using Game;

namespace RuthlessConquest {
    public class GameScreen : Screen {
        public PlayerLabelWidget[] publicPlayerLabels = new PlayerLabelWidget[7];
        public bool DisconnectedDialogShown;
        public const string fName = "RCGameScreen";
        public Server Server { get; set; }
        public Client Client { get; set; }
        public GameWidget GameWidget { get; }
        public IReadOnlyList<PlayerLabelWidget> PlayerLabels => publicPlayerLabels;
        public MessagesListWidget MessagesListWidget { get; }
        public MessageWidget ConnectionInterruptionMessageWidget { get; set; }
        public AliensAttackMessageWidget AliensAttackMessageWidget { get; set; }
        public ReinforcementsMessageWidget ReinforcementsMessageWidget { get; set; }

        public GameScreen() {
            IsDrawRequired = true;
            IsOverdrawRequired = true;
            Children.Add(new BackgroundWidget { ShiftSpeed = 0f, Density = 0.6f, Brightness = 0.7f });
            Children.Add(GameWidget = new GameWidget());
            for (int i = 0; i < publicPlayerLabels.Length; i++) {
                publicPlayerLabels[i] = new PlayerLabelWidget(this, i);
                Children.Add(publicPlayerLabels[i]);
            }
            MessagesListWidget = new MessagesListWidget {
                HorizontalAlignment = WidgetAlignment.Center,
                VerticalAlignment = WidgetAlignment.Far,
                Margin = new Vector2(0f, SettingsManager.DisplayPlayerStatistics ? 72f : 36f)
            };
            Children.Add(MessagesListWidget);
            Children.Add(
                new StackPanelWidget {
                    IsHitTestVisible = false,
                    HorizontalAlignment = WidgetAlignment.Center,
                    VerticalAlignment = WidgetAlignment.Center,
                    Direction = LayoutDirection.Vertical,
                    Children = {
                        (ConnectionInterruptionMessageWidget = new MessageWidget()),
                        (AliensAttackMessageWidget = new AliensAttackMessageWidget()),
                        (ReinforcementsMessageWidget = new ReinforcementsMessageWidget())
                    }
                }
            );
        }

        public override void Enter(object[] parameters) {
            Server = (Server)parameters[0];
            Client = (Client)parameters[1];
            Client.Game.Screen = this;
            GameWidget.Client = Client;
            MessagesListWidget.ClearMessages();
            if (Client.Game.CreationParameters.MaxHumanPlayersCount <= 1) {
                Client.StartGame();
                DialogsManager.ShowDialog(GameWidget, new CountdownDialog(Client));
            }
            else {
                DialogsManager.ShowDialog(this, new WaitingForPlayersDialog(Client));
            }
            if (Server != null
                && Server.IsUsingInProcessTransmitter
                && !SettingsManager.DontShowInstructions) {
                DialogsManager.ShowDialog(null, new GameMenuDialog(this, true));
            }
        }

        public override void Leave() {
            foreach (PlayerLabelWidget playerLabel in PlayerLabels) {
                playerLabel.Player = null;
            }
            MusicManager.CurrentMix = MusicManager.Mix.InGame;
            GameWidget.Client = null;
            Client.Dispose();
            Client = null;
            Server?.Dispose();
            Server = null;
            DialogsManager.HideAllDialogs();
        }

        public override void Update() {
            if (!Client.IsConnected) {
                if (!DisconnectedDialogShown) {
                    DisconnectedDialogShown = true;
                    DialogsManager.ShowDialog(
                        this,
                        new MessageDialog(
                            LanguageControl.Get(fName, "1"),
                            LanguageControl.Get(fName, "2"),
                            LanguageControl.Ok,
                            null,
                            delegate { ScreensManager.SwitchScreen("RCMainMenu"); }
                        )
                    );
                }
            }
            else {
                DisconnectedDialogShown = false;
            }
            if (Input.Back) {
                DialogsManager.ShowDialog(this, new GameMenuDialog(this, false));
            }
        }

        public override void Draw(DrawContext dc) {
            if (!ScreensManager.IsAnimating) {
                Display.Clear(Color.Black, 1f, 0);
            }
        }

        public override void Overdraw(DrawContext dc) {
            if (Server != null
                && Server.Games.Any(g => g.DesyncDetected)) {
                dc.PrimitivesRenderer2D.FontBatch(null, 1000).QueueText(LanguageControl.Get(fName, "3"), Vector2.Zero, 0f, Color.Gray);
            }
        }

        public void Disconnect() {
            DisconnectedDialogShown = true;
            Client.DisconnectFromGame();
            ScreensManager.SwitchScreen("RCMainMenu");
        }

        public PlayerLabelWidget FindPlayerLabel(Player player) {
            foreach (PlayerLabelWidget playerLabel in PlayerLabels) {
                if (playerLabel.Player == player) {
                    return playerLabel;
                }
            }
            return null;
        }
    }
}